package com.gitee.wsl.transform.encode.unicode

import com.gitee.wsl.ext.base.isAsciiPrintable
import com.gitee.wsl.transform.encode.hex.HexUtil
import kotlin.jvm.JvmOverloads


/**
 * 提供Unicode字符串和普通字符串之间的转换
 *
 * @author 兜兜毛毛, looly
 * @since 4.0.0
 */
object Unicode {
    /**
     * Unicode字符串转为普通字符串<br></br>
     * Unicode字符串的表现方式为：\\uXXXX
     *
     * @param unicode Unicode字符串
     * @return 普通字符串
     */
    fun toString(unicode: String): String {
        if (unicode.isBlank()) {
            return unicode
        }

        val len = unicode.length
        val sb= StringBuilder(len)
        var i: Int
        var pos = 0
        while ((unicode.indexOf( "\\u", pos,true).also { i = it }) != -1) {
            sb.append(unicode, pos, i) //写入Unicode符之前的部分
            pos = i
            if (i + 5 < len) {
                val c: Char
                try {
                    c = unicode.substring(i + 2, i + 6).toInt(16).toChar()
                    sb.append(c)
                    pos = i + 6 //跳过整个Unicode符
                } catch (e: NumberFormatException) {
                    //非法Unicode符，跳过
                    sb.append(unicode, pos, i + 2) //写入"\\u"
                    pos = i + 2
                }
            } else {
                //非Unicode符，结束
                break
            }
        }

        if (pos < len) {
            sb.append(unicode, pos, len)
        }
        return sb.toString()
    }

    /**
     * 字符编码为Unicode形式
     *
     * @param c 被编码的字符
     * @return Unicode字符串
     * @since 5.6.2
     * @see HexUtil.toUnicodeHex
     */
    fun toUnicode(c: Char): String {
        return HexUtil.toUnicodeHex(c)
    }

    /**
     * 字符编码为Unicode形式
     *
     * @param c 被编码的字符
     * @return Unicode字符串
     * @since 5.6.2
     * @see HexUtil.toUnicodeHex
     */
    fun toUnicode(c: Int): String {
        return HexUtil.toUnicodeHex(c)
    }

    /**
     * 字符串编码为Unicode形式
     *
     * @param str         被编码的字符串
     * @param isSkipAscii 是否跳过ASCII字符（只跳过可见字符）
     * @return Unicode字符串
     */
    /**
     * 字符串编码为Unicode形式
     *
     * @param str 被编码的字符串
     * @return Unicode字符串
     */
    @JvmOverloads
    fun toUnicode(str: String, isSkipAscii: Boolean = true): String {
        if (str.isEmpty()) {
            return str
        }

        val len = str.length
        val unicode = StringBuilder(str.length * 6)
        var c: Char
        for (i in 0..<len) {
            c = str[i]
            if (isSkipAscii && c.isAsciiPrintable) {
                unicode.append(c)
            } else {
                unicode.append(HexUtil.toUnicodeHex(c))
            }
        }
        return unicode.toString()
    }
}

fun String.encodeToUnicode(isSkipAscii: Boolean = true) = Unicode.toUnicode(this,isSkipAscii)

fun Char.encodeToUnicode() = Unicode.toUnicode(this)

fun String.decodeUnicodeToString() = Unicode.toString(this)

